#!/usr/bin/env python
# Copyright (c) 2006-2008 Mitch Garnaat http://garnaat.org/
#
# Permission is hereby granted, free of charge, to any person obtaining a
# copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish, dis-
# tribute, sublicense, and/or sell copies of the Software, and to permit
# persons to whom the Software is furnished to do so, subject to the fol-
# lowing conditions:
#
# The above copyright notice and this permission notice shall be included
# in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
# OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABIL-
# ITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
# SHALL THE AUTHOR BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, 
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
# IN THE SOFTWARE.
import sys
from optparse import OptionParser
from boto.mapreduce.partitiondb import PartitionDB, Partition, Version
from boto.exception import SDBPersistenceError
from boto.sdb.persist import get_manager, get_domain

USAGE = """
  SYNOPSIS
    %prog [options]
  DESCRIPTION
    List and describe your PartitionDBs.
    Called with no options, all PartitionDB objects defined in your default
    domain (as specified in the "default_domain" option in the "[Persist]"
    section of your boto config file) will be listed.
    When called with a particular PartitionDB name (using -p option) all
    Version objects of that PartitionDB object will be listed.
    When called with the -p option and a particular Version name specified
    (using the -v option) all Partitions in that Version object will be listed.
"""
class Describe:

    def __init__(self):
        self.parser = OptionParser(usage=USAGE)
        self.parser.add_option('-d', '--domain-name', action='store', type='string',
                               help='name of the SimpleDB domain where PDB objects are stored')
        self.parser.add_option('-n', '--num-entries', action='store', type='int',
                               help='maximum number of entries to print (default 100)')
        self.parser.set_defaults(num_entries=100)
        self.parser.add_option('-p', '--pdb-name', action='store', type='string',
                               help='name of the PDB to describe')
        self.parser.add_option('-v', '--version-name', action='store', type='string',
                               help='name of the PDB Version to describe')
        self.options, self.args = self.parser.parse_args()
        self.prog_name = sys.argv[0]

    def describe_all(self):
        print 'Using SimpleDB Domain: %s' % get_domain()
        print 'PDBs:'
        rs = PartitionDB.list()
        i = 0
        for pdb in rs:
            print '%s\t%s\t%s' % (pdb.id, pdb.name, pdb.bucket_name)
            i += 1
            if i == self.options.num_entries:
                break

    def describe_pdb(self, pdb_name):
        print 'Using SimpleDB Domain: %s' % get_domain()
        print 'PDB: %s' % pdb_name
        print 'Versions:'
        try:
            pdb = PartitionDB.get(name=pdb_name)
            i = 0
            for v in pdb.versions:
                if v.date:
                    ds = v.date.isoformat()
                else:
                    ds = 'unknown'
                print '%s\t%s\t%s' % (v.id, v.name, ds)
                i += 1
                if i == self.options.num_entries:
                    break
            cv = pdb.current_version()
            if cv:
                print 'Current Version: %s' % cv.name
            else:
                print 'Current Version: None'
        except SDBPersistenceError:
            self.parser.error('pdb_name (%s) unknown' % pdb_name)

    def describe_version(self, pdb_name, version_name):
        print 'Using SimpleDB Domain: %s' % get_domain()
        print 'PDB: %s' % pdb_name
        print 'Version: %s' % version_name
        print 'Partitions:'
        try:
            pdb = PartitionDB.get(name=pdb_name)
            for v in pdb.versions:
                if v.name == version_name:
                    i = 0
                    for p in v.partitions():
                        print '%s\t%s' % (p.id, p.name)
                        i += 1
                        if i == self.options.num_entries:
                            break
        except SDBPersistenceError:
            self.parser.error('pdb_name (%s) unknown' % pdb_name)

    def main(self):
        self.options, self.args = self.parser.parse_args()
        self.manager = get_manager(self.options.domain_name)
            
        if self.options.pdb_name:
            if self.options.version_name:
                self.describe_version(self.options.pdb_name, self.options.version_name)
            else:
                self.describe_pdb(self.options.pdb_name)
        else:
            self.describe_all()
            
if __name__ == "__main__":
    describe = Describe()
    describe.main()
